<!--
 * @Descripttion: 
 * @Author: yuxi
 * @Date: 2022-09-15 14:58:04
 * @LastEditors: yuxi
 * @LastEditTime: 2023-08-25 22:24:36
-->
<template>
  <div class="map-container">
    <MiningMap
      :center="center"
      :zoom="zoom"
      :useContextMenu="true"
      :customContextMenus="customContextMenus"
      :log="true"
    >
      <MiningTiandituLayer
        layerName="基础底图"
        :ak="key"
        @ready="ready"
        layerType="img_w"
      ></MiningTiandituLayer>
      <MiningVectorLayer
        :featureStyle="getLayerStyle(layer)"
        v-for="layer in layers"
        :key="layer.layerId"
        :layerName="layer.layerName"
        :layerId="layer.layerId"
        :properties="layer"
        @ready="reloadLayerControl"
      >
        <MiningLineString
          v-for="feature in groupFeatures[layer.layerId]"
          :key="feature.get('properties').id"
          :canModifyGeom="true"
          :canModifyStyle="true"
          :canRemove="true"
          :feature="feature"
          @remove="handleRemove"
          @updated="handleLineUpdated"
        >
        </MiningLineString>
        <MiningPoint
          v-for="feature in groupPoints[layer.layerId]"
          :key="feature.get('properties').id"
          :feature="feature"
          :canModifyGeom="true"
          :canModifyStyle="true"
          :canRemove="true"
          @remove="handleRemovePoint"
          @updated="handlePointUpdated"
        >
        </MiningPoint>
      </MiningVectorLayer>

      <MiningLayerControl ref="layerControl">
        <template #layer="{ layer, layer_index, properties }">
          <MiningLayerControlItem :layer="layer">
            <template #addon>
              <!-- <i class="el-icon-edit"></i> -->
              <!-- <i v-if="layer_index > 0 && !properties.isLock" class="el-icon-lock" @click="startEdit(layer)" style="margin-right: 5px;"></i>
                <i v-if="layer_index > 0 && properties.isLock" class="el-icon-unlock" @click="endEdit(layer)" style="margin-right: 5px;"></i>
                <i v-if="layer_index > 0" class="el-icon-delete" @click="removeLayer(layer)"></i> -->

              <el-tooltip
                v-if="layer_index > 0"
                content="修改样式"
                placement="top"
              >
                <img
                  src="@/assets/images/style.png"
                  class="icon"
                  @click="handleEditStyle(layer)"
                  alt="编辑样式"
                />
              </el-tooltip>
            </template>
          </MiningLayerControlItem>
        </template>
        <template #extend>
          <div class="add-btn">
            <!-- <el-button size="small" @click="handleAddLayer">添加图层</el-button> -->
          </div>
        </template>
      </MiningLayerControl>
      <MiningStyleControl
        v-if="editLayerStyle"
        :defaultStyle="editLayerStyle"
        @submit="handleLayerStyleUpdated"
        @cancel="handleLayerStyleCancel"
      ></MiningStyleControl>
    </MiningMap>
  </div>
</template>

<script>
import MiningMap from 'mining-map/Map'
import MiningTiandituLayer from 'mining-map/Layers/TiandituLayer'
import { TiandituKey } from '@/config/config.js';
import { Draw,  Snap, Select } from 'ol/interaction';
import {Circle as CircleStyle, Fill, Stroke, Style, Stroke as StrokeStyle, Fill as FillStyle,Icon} from 'ol/style';
import {Vector as VectorSource} from 'ol/source';
import {  Vector as VectorLayer} from 'ol/layer';
import { pointerMove } from 'ol/events/condition';
import MiningLayerControl from 'mining-map/Control/LayerControl';
import MiningLayerControlItem from 'mining-map/Control/LayerControlItem';
import MiningVectorLayer from 'mining-map/Layers/VectorLayer'
import MiningPoint from 'mining-map/Features/Point';
import MiningLineString from 'mining-map/Features/LineString';
import MiningStyleControl from 'mining-map/Control/StyleControl';

import marker from '@/assets/images/light.png'
import {findAndCountAll, createOne, deleteOne, updateOne} from '@/apis/attr'

import {createOne as createGeo, findAndCountAll as findAllGeos, splitLine, updateOne as updateGeo, deleteOne as deleteGeo } from '@/apis/geo'

import GeoJSON from 'ol/format/GeoJSON';
import Feature from 'ol/Feature';
import Polygon from 'ol/geom/Polygon';
import LineString from 'ol/geom/LineString';
import Point from 'ol/geom/Point';
import Collection from 'ol/Collection';
import { MiningStyle } from 'mining-map/Style';
import { DefaultStyle } from 'mining-map/Config';

const source = new VectorSource();
const vector = new VectorLayer({
  name: 'EditLayer',
  source: source,
  style: new Style({
    fill: new Fill({
      color: 'rgba(255, 255, 255, 0.2)',
    }),
    stroke: new Stroke({
      color: '#ffcc33',
      width: 2,
    }),
    image: new CircleStyle({
      radius: 7,
      fill: new Fill({
        color: '#ffcc33',
      }),
    }),
  }),
});
export default {
  name: 'PointModify',
  title: '要素及样式修改',
  parentTitle: '业务组件',
  components: {
    MiningMap,
    MiningTiandituLayer,
    MiningLayerControl,
    MiningLayerControlItem,
    MiningVectorLayer,
    MiningLineString,
    MiningPoint,
    MiningStyleControl
  },
  data () {
    const style = new Style({
      stroke: new StrokeStyle({
        color: 'blue',
        lineDash: [4],
        width: 3,
      }),
      fill: new FillStyle({
        color: 'rgba(0, 0, 255, 0.1)',
      }),
      image: new Icon({
        anchor: [0.5, 1],
        anchorXUnits: 'fraction',
        anchorYUnits: 'fraction',
        // size: [5, 15],
        // size: new olSize(15, 15),
        scale: 0.2,
        src: marker,
      })
    })
    return {
      center: [116.43396401346438,39.926523711148874],
      zoom: 17,
      key: TiandituKey,
      draw: null,
      snap: null,
      select: null,
      layers: [],
      style,
      map: null,
      features: [],
      selectFeature: null,
      points: [],
      editLayerStyle: null,
      updateStyleLayer: null
    }
  },
  created() {
    this.fetchLayers() 
  },
  computed:{
    editLayer () {
      return this.layers.find(l => {
        return l.isLock
      })
    },
    groupFeatures () {
      let groups = {}
      this.features.map(f => {
        let properties = f.get('properties')
        groups[properties.layer_id]= groups[properties.layer_id] || []
        groups[properties.layer_id].push(f)
      })

      return groups
    },
    groupPoints () {
      let groups = {}
      this.points.map(f => {
        let properties = f.get('properties')
        groups[properties.layer_id]= groups[properties.layer_id] || []
        groups[properties.layer_id].push(f)
      }) 
      return groups
    },
    customContextMenus () {
      return this.selectFeature ? [{
        name: '分割选中折线',
        handler: this.handleSplit
      }]:[]
    }
  },
  watch: {
    editLayer () {
      //  
    },
    groupFeatures () {
      console.log('groupFeatures', this.groupFeatures)
    }
  },
  methods: {
    ready ({ map }) {
      this.map = map
    },
    getLayerStyle(layer) {
      if(layer.style) {
        let style = new MiningStyle()
        style.fromJSON(JSON.parse(layer.style))
        console.log(style)
        return style
      } else {
        return this.style
      }
    },
    // 获取所有图层
    fetchLayers () {
      this.layers = []
      findAndCountAll({
        table: 'layer_info',
        page:1,
        pageSize: 100
      }).then(res => { 
        if(res.code === 0) {
          this.layers = res.data.rows.filter(r => {
            return !r.geom
          })
          .map(r => {
            return {
              layerId: r.id,
              layerName: r.name,
              type: 'vectorLayer',
              isLock: r.isLock,
              style: r.style
            }
          })
          console.log('this.layers is', this.layers)
          this.fetchAllLines()
          this.$nextTick(() => {
            // this.reloadLayerControl()
          })
        }
      })
    },
    // 获取所有要素点
    fetchAllLines () {
      findAllGeos({
        table: 'line',
        page:1,
        pageSize: 100
      }).then(res => { 
        if(res.code === 0) {
          this.features = res.data.rows.map(r => {
            let feature =  new Feature({
              type: 'LineString',
              geometry: new GeoJSON().readGeometry(r.geom),
              name: r.id,
              properties: {
                id: r.id,
                layer_id: r.layer_id,
                style: r.style
              }
            })
            let style = null
            console.log(r.style)
            if(r.style) {
              style = new MiningStyle()
              style.fromJSON(JSON.parse(r.style))
              feature.setStyle(style)
            }
            return feature
          })
          this.fetchAllPoint()
        }
      })
      
    },
    fetchAllPoint() {
      findAllGeos({
        table: 'point',
        page:1,
        pageSize: 1000
      }).then(res => { 
        if(res.code === 0) {
          this.points = res.data.rows.map(r => {
            return new Feature({
              type: 'Point',
              geometry: new GeoJSON().readGeometry(r.geom),
              name: r.id,
              properties: {
                id: r.id,
                layer_id: r.layer_id,
                line_id: r.line_id,
                style: r.style

              }
            })
          })
          
        }
      })
    },       
    reloadLayerControl () {
      this.$refs.layerControl.load() 
    },
    handleLineUpdated (feature) {
      console.log('handleUpdated', feature)
      this._updateLine(feature)
    },
    _updateLine(feature) {
      const featureGeoJSON = new GeoJSON().writeFeatureObject(feature)
      updateGeo({
        table: 'line',
        geom: featureGeoJSON.geometry,
        layer_id: featureGeoJSON.properties.properties.layer_id,
        id: featureGeoJSON.properties.properties.id,
        style: featureGeoJSON.properties.properties.style,
      }).then(res  => {
        if(res.code === 0) {
           this.$message.success('更新完成')
        }
      }).finally(() => {
        // source.refresh()
      })
    },
    handlePointUpdated (feature) {
      console.log('handlePointUpdated', feature)
      this._updatePoint(feature)
    },
    _updatePoint(feature) {
      const featureGeoJSON = new GeoJSON().writeFeatureObject(feature)
      updateGeo({
        table: 'point',
        geom: featureGeoJSON.geometry,
        layer_id: featureGeoJSON.properties.properties.layer_id,
        id: featureGeoJSON.properties.properties.id,
        style: featureGeoJSON.properties.properties.style,
      }).then(res  => {
        if(res.code === 0) {
           this.$message.success('更新完成')
        }
      }).finally(() => {
        // source.refresh()
      })
    },
    handleEditStyle (layer) {
      console.log(layer)
      let properties = layer.get('properties')
      console.log(properties)
      this.updateStyleLayer = layer
      let layerStyleObj =  properties.style
      let layerStyle = null
      if(layerStyleObj) {
        layerStyleObj = JSON.parse(layerStyleObj)
        layerStyle = new MiningStyle()
        layerStyle.fromJSON(layerStyleObj)
      } else {
        layerStyle = new MiningStyle()
        layerStyle.fromJSON(DefaultStyle)
      }
      this.editLayerStyle = layerStyle  
    },
    handleLayerStyleUpdated (style) {
      console.log('update layer style', style)
      let styleObj = style.toJSON()
      let properties = this.updateStyleLayer.get('properties')
      console.log(properties)
      updateOne({
        table: 'layer_info',
        id: properties.layerId,
        style: JSON.stringify(styleObj)
      }).then(res => {
        this.updateStyleLayer = null
        this.editLayerStyle = null
        this.fetchLayers()

      })
      console.log(styleObj)
    },
    handleLayerStyleCancel () {
      this.updateStyleLayer = null
      this.editLayerStyle = null
    },
    handleRemove (feature) {
      console.log(feature)
      this.$confirm('是否确认删除当前对象?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
           this._removeLine(feature)
        }).catch(() => {
                  
        });
    },
    handleRemovePoint (feature) {
      this.$confirm('是否确认删除当前对象?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this._removePoint(feature)
        }).catch(() => {
                  
        });
    },
    
    _removeLine (feature) {
      const featureGeoJSON = new GeoJSON().writeFeatureObject(feature)
      let lineId = featureGeoJSON.properties.properties.id
      deleteGeo({
        table: 'line', 
        id: lineId, 
      }).then(res  => {
        if(res.code === 0) {
           this.fetchAllLines()
           this._removePointByLineId(lineId)
        }
      }).finally(() => {
        // source.refresh()
      })
    },
    _removePointByLineId (lineId) {
      let points = this.points.filter(p => {
        const featureGeoJSON = new GeoJSON().writeFeatureObject(p)
        let _lineId = featureGeoJSON.properties.properties.line_id
        return _lineId === lineId
      }).map(p => {
        const featureGeoJSON = new GeoJSON().writeFeatureObject(p)
        return featureGeoJSON.properties.properties.id
      })
      points = points.map(async p => {
        return deleteGeo({
          table: 'point', 
          id: p, 
        }) 
      })
      Promise.all(points).then(() => {
        this.$message.success('删除成功')
        this.fetchAllPoint()
      })
      
    },
    _removePoint (feature) {
      const featureGeoJSON = new GeoJSON().writeFeatureObject(feature)
      deleteGeo({
        table: 'point', 
        id: featureGeoJSON.properties.properties.id, 
      }).then(res  => {
        if(res.code === 0) {
           this.$message.success('删除成功')
           this.fetchAllPoint()
        }
      }).finally(() => {
        // source.refresh()
      })
    }
  }

}
</script>

<style lang="less">
body,
html {
  padding: 0;
  margin: 0;
}

.map-container {
  width: 100%;
  height: 100vh;
  text-align: left;
  .add-btn {
    padding: 20px;
    text-align: center;
  }
}
</style>